
public class LineEventProcessor extends DrawObjectEventProcessor
{
	private DrawObject TryCreateLine(MainWindow.GUIElements GUIElements, KeyEventProcessor KeyEventProcessor, MouseEventProcessor MouseEventProcessor, ObjectStorage Objects, DrawObject LineStart, DrawObject SingleSelectedObject)
	{
		if (UNDEFINED(SingleSelectedObject))
		{
			// when user just clicks on Grid, drawing Line is aborted

			LineStart = UNDEFINED;

			return LineStart;
		}

		DrawObject LastSelectedObject = SingleSelectedObject;

		// we check DrawObject types via "instanceof", special in this method,
		// because clearer like this here:

		if (LastSelectedObject instanceof TextField ||
			LastSelectedObject instanceof Neuron ||
			LastSelectedObject instanceof NeuronInputNode ||
			LastSelectedObject instanceof NeuronOutputNode ||
			LastSelectedObject instanceof Node ||
			LastSelectedObject instanceof SampleAndHoldInputNode ||
			LastSelectedObject instanceof SampleAndHoldOutputNode ||
			LastSelectedObject instanceof VisualFieldPixel)
		{
			if (UNDEFINED(LineStart))
			{
				if (!(LastSelectedObject instanceof Neuron) &&
					!(LastSelectedObject instanceof SampleAndHold))
				{
					LineStart = LastSelectedObject;
				}
			}
			else if (
				LineStart == LastSelectedObject)
			{
				LineStart = UNDEFINED;
			}
			else if (
				LineStart instanceof Line ||
				LineStart instanceof Neuron || // START must not be Neuron!
				LineStart instanceof NeuronInputField ||
				LineStart instanceof SampleAndHold ||
				LineStart instanceof VisualField)
			{
				LineStart = UNDEFINED;
			}
			else if (
				LastSelectedObject instanceof Line ||
				LastSelectedObject instanceof NeuronInputField ||
				LastSelectedObject instanceof VisualField)
			{
				LineStart = UNDEFINED;
			}
			else if (
				((LineStart instanceof NeuronInputNode && LastSelectedObject instanceof NeuronOutputNode) && (LineStart.GetParentDrawObject() == LastSelectedObject.GetParentDrawObject())) ||
				((LineStart instanceof NeuronInputNode && LastSelectedObject instanceof NeuronInputNode) && (LineStart.GetParentDrawObject() == LastSelectedObject.GetParentDrawObject())) ||
				((LineStart instanceof SampleAndHoldInputNode && LastSelectedObject instanceof SampleAndHoldOutputNode) && (LineStart.GetParentDrawObject() == LastSelectedObject.GetParentDrawObject())) ||
				((LineStart instanceof SampleAndHoldInputNode && LastSelectedObject instanceof SampleAndHoldInputNode) && (LineStart.GetParentDrawObject() == LastSelectedObject.GetParentDrawObject())) ||
				((LineStart instanceof VisualFieldPixel && LastSelectedObject instanceof VisualFieldPixel) && (LineStart.GetParentDrawObject() == LastSelectedObject.GetParentDrawObject())))
			{
				LineStart = UNDEFINED;
			}
			else if (
				((LastSelectedObject instanceof NeuronInputNode && LineStart instanceof NeuronOutputNode) && (LineStart.GetParentDrawObject() == LastSelectedObject.GetParentDrawObject())) ||
				((LastSelectedObject instanceof NeuronInputNode && LineStart instanceof NeuronInputNode) && (LineStart.GetParentDrawObject() == LastSelectedObject.GetParentDrawObject())) ||
				((LastSelectedObject instanceof SampleAndHoldInputNode && LineStart instanceof SampleAndHoldOutputNode) && (LineStart.GetParentDrawObject() == LastSelectedObject.GetParentDrawObject())) ||
				((LastSelectedObject instanceof SampleAndHoldInputNode && LineStart instanceof SampleAndHoldInputNode) && (LineStart.GetParentDrawObject() == LastSelectedObject.GetParentDrawObject())) ||
				((LastSelectedObject instanceof VisualFieldPixel && LineStart instanceof VisualFieldPixel) && (LineStart.GetParentDrawObject() == LastSelectedObject.GetParentDrawObject())))
			{
				LineStart = UNDEFINED;
			}
			else if (Objects.ExistsLineFromTo(LineStart, LastSelectedObject)) // two lines in contrary directions allowed (flow donator loop or so)
			{
				LineStart = UNDEFINED;
			}
			else
			{
				Objects.AddObject("Line", LineStart, LastSelectedObject);

				LineStart = UNDEFINED;
			}
		}
		else
		{
			LineStart = UNDEFINED; // either a Line is created (see above), or attempt to create Line is aborted (else confusing)
		}

		return LineStart;
	}

	@Override
	public void TryProcessUserKeyboardAction(MainWindow.GUIElements GUIElements, KeyEventProcessor KeyEventProcessor, MouseEventProcessor MouseEventProcessor, ObjectStorage ObjectStorage, IOProgram IOProgram)
	{
		if (!(KeyboardEventsToBeProcessed(GUIElements)))
			return;

		return;
	}

	@Override
	public void TryProcessUserMouseAction(MainWindow.GUIElements GUIElements, KeyEventProcessor KeyEventProcessor, MouseEventProcessor MouseEventProcessor, ObjectStorage ObjectStorage, IOProgram IOProgram)
	{
		if (!(MouseEventsToBeProcessed(GUIElements)))
			return;

		// ****************************************************************
		if (MouseEventProcessor.IsMouseDragged() &&
			MouseEventProcessor.AnyButtonPressed())
		{
			if (DEFINED(LineStart))
			{
				LineStart = UNDEFINED;

				GUIElements.GetMainWindow().DoRedraw();
			}
		}
		// ****************************************************************
		if (MouseEventProcessor.IsLeftButtonClicked() &&
			NOT(KeyEventProcessor.AnyKeyPressed()) &&
			NOT(MultiSelectionExisting))
		{
			DrawObject LineStartOld = LineStart;

			LineStart = TryCreateLine(GUIElements, KeyEventProcessor, MouseEventProcessor, ObjectStorage, LineStart, SingleSelectedObject);
			
			if (LineStart != LineStartOld)
			{
				GUIElements.GetMainWindow().DoRedraw();
			}

			MoveMousePosLast = UNDEFINED_POINT; // no button pressed, no moving!
		}

		// ****************************************************************
		if (DEFINED(LineStart))
		{
			CursorManager.SetCrosshairCursorEnabled(true);
		}
		else
		{
			CursorManager.SetCrosshairCursorEnabled(false);
		}

		return;
	}
}
